package org.example.weather.bigscreen.core.config;

import com.google.common.collect.Range;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.*;

public class QuarterDbAlgorithm implements StandardShardingAlgorithm<Date> {
    private Properties props;

    @Override
    public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Date> shardingValue) {
        Date uploadDate = shardingValue.getValue();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(uploadDate);
        int month = calendar.get(Calendar.MONTH) + 1;
        if (CollectionUtils.isNotEmpty(availableTargetNames)) {
            for (final String dbName : availableTargetNames) {
                String shardIndex = dbName.substring(dbName.lastIndexOf("_") + 1);
                if (StringUtils.equals(shardIndex, String.valueOf((month % 3 == 0 ? month / 3 : month / 3 + 1) - 1))) {
                    return dbName;
                }
            }
        }
        return null;
    }

    @Override
    public Collection<String> doSharding(final Collection<String> availableTargetNames,
                                         final RangeShardingValue<Date> shardingValue) {
        Collection<String> result = new ArrayList<>();
        Range<Date> dateRange = shardingValue.getValueRange();
        Date upperEndpoint = dateRange.upperEndpoint();
        Date lowerEndpoint = dateRange.lowerEndpoint();
        Set<String> shardedIndexSet = new HashSet<>();
        while (lowerEndpoint.compareTo(upperEndpoint) < 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(lowerEndpoint);
            int month = calendar.get(Calendar.MONTH) + 1;
            shardedIndexSet.add(String.valueOf((month % 3 == 0 ? month / 3 : month / 3 + 1) - 1));
            lowerEndpoint = DateUtils.addDays(lowerEndpoint, 1);

        }
        if (CollectionUtils.isNotEmpty(availableTargetNames)) {
            for (final String dbName : availableTargetNames) {
                String shardIndex = dbName.substring(dbName.lastIndexOf("_") + 1);
                if (shardedIndexSet.contains(shardIndex)) {
                    result.add(dbName);
                }
            }
        }
        return result;
    }

    @Override
    public Properties getProps() {
        return props;
    }

    public void setProps(final Properties props) {
        this.props = props;
    }

    @Override
    public void init(final Properties properties) {
        System.out.println("QuarterDbAlgorithm init");
    }
}
